#include "device/Keyboard.h"

bool Keyboard::read(word_t start_addr, size_t length, uint8_t *buffer, bool &mmio) {
    word_t offset = start_addr - KEYBOARD_BASE;
    assert(offset == 0 && length == 4);
    mmio = true;
    uint32_t key = _KEY_NONE;
    if (!key_queue.empty()) {
        key = key_queue.front();
        key_queue.pop_front();
    }
    memcpy(buffer, &key, length);
    return true;
}

bool Keyboard::write(word_t start_addr, size_t length, const uint8_t *buffer, bool &mmio) {
    mmio = true;
    return false;
}

void Keyboard::update() {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch (event.type) {
            case SDL_QUIT:
                exit(0);
            case SDL_KEYDOWN:
            case SDL_KEYUP: {
                auto key = event.key.keysym.scancode;
                bool is_keydown = (event.key.type == SDL_KEYDOWN);
                if (keymap[key] != _KEY_NONE) {
                    key_queue.push_back(keymap[key] | (is_keydown ? KEYDOWN_MASK : 0));
                }
                break;
            }
            default:
                break;
        }
    }
}
